package cn.qayy.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import cn.qayy.constants.Constant;
import cn.qayy.dao.BasisMapper;
import cn.qayy.dao.SynchronizationMapper;
import cn.qayy.dto.BasisDTO;
import cn.qayy.po.Basis;
import cn.qayy.po.CargoInvoiceApply;
import cn.qayy.service.IBasisService;
import cn.qayy.service.SynchronizationService;
import cn.qayy.service.Uploadable;
import cn.qayy.utils.DateUtils;
import cn.qayy.utils.DownLoadUtil;
import cn.qayy.utils.ServletContextUtils;
import cn.qayy.utils.StringUtil;

/***
 * @author wy
 *
 */
@SuppressWarnings("all")
@Service("basisServiceImpl")
public class BasisImpl implements IBasisService {
	private Logger logger = LoggerFactory.getLogger(BasisImpl.class);

	@Resource
	public BasisMapper basisMapper;
	
	@Resource(name = "synchronizationImpl")
	private SynchronizationService synchronizationService;

	@Override
	public PageInfo<Basis> selectForList(Map<String, Object> params) throws Exception {
		if (params != null && params.size() > 0) {
			//下载时记住当时查询的条件
			DownLoadUtil.set("BasisDTO",params);
			
			PageHelper.startPage(StringUtil.parseInt(params.get("pageNumber").toString()), StringUtil.parseInt(params.get("pageSize").toString()));
			List<Basis> list = basisMapper.selectForList(params);
			PageInfo<Basis> pageInfo = new PageInfo<Basis>(list);
			return pageInfo;
		}
		return null;
	}

	@Override
	public List<BasisDTO> selectBasisForDown(@RequestParam Map<String, Object> params) {
		List<BasisDTO> list = basisMapper.selectBasisForDown(params);
		return list;
	}

	@Override
	public Basis selectByID(@RequestParam Integer id) {
		return basisMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<? extends String> selectBasicKeys() {
		return basisMapper.selectBasicKeys();
	}

	@Override
	public List<? extends Map<String, String>> selectAllProvincesAndCityAndCountry() {
		return basisMapper.selectAllProvincesAndCityAndCountry();
	}

	@Override
	public int insertByList(List list) {
		return basisMapper.insertByList(list);
	}

	@Override
	public int updateByList(List list) {
		return basisMapper.updateByList(list);
	}

	@Override
	public int deleteByList(List list) throws Exception {
		List basics = basisMapper.selectByIds(list);
		removeToContext(basics);//移除缓存
		return basisMapper.deleteByIdList(list);
	}

	@Override
	public int insert(Object entity) {
		return basisMapper.insertSelective(entity);
	}

	@Override
	public int update(Object entity) {
		return basisMapper.updateByPrimaryKeySelective(entity);
	}

	@Override
	public int delete(Object bean) {
		return 0;
	}

	@Override
	public void updateByPCC(Map<String, Object> params) {
		basisMapper.updateByPCC(params);
	}

	@Override
	public List selectProvinceByMgr(String mgr) throws Exception {
		return basisMapper.selectProvinceByMgr(mgr);
	}

	@Override
	public List<Integer> selectIdsByMap(Map<String, Object> params) {
		return basisMapper.selectIdsByMap(params);
	}

	@Override
	public List<String> selectMgrOfProvinceByMgr(Map<String, Object> params) {
		return basisMapper.selectMgrOfProvinceByMgr(params);
	}

	@Override
	public List<Basis> selectByMap(Map<String, Object> params) {
		return basisMapper.selectByMap(params);
	}
	
	@Override
	public String selectSpaceByMgr(String params) {
		return basisMapper.selectSpaceByMgr(params);
	}

	@Override
	public void persistence(Map<String, List<Uploadable>> map,HttpServletRequest request,HttpServletResponse response) throws Exception{
		//获取更新的省份、地市、区县，用于同步更新
		Set<String> provinces = new HashSet<String>(Constant.INIT_CAPACITY*4);
		Set<String> citys = new HashSet<String>(Constant.SMALL_CAPACITY);
		Set<String> countrys = new HashSet<String>(Constant.SMALL_CAPACITY);
		
		//批量更新
		List<Uploadable> listE = map.get("E");
		if(listE!=null && !listE.isEmpty()) {
			/**待更新的实体list**/
			List<Basis> list = new ArrayList<Basis>(listE.size()+1);
			List<Basis> db_list = new ArrayList<Basis>(listE.size()+1);
			List<String> ids = new ArrayList<String>(listE.size()+1);
			for (Uploadable u : listE) {
				BasisDTO dto = (BasisDTO)u;
				ids.add(dto.getId());
			}
			db_list = basisMapper.selectByIds(ids);
			//校验Excel上传的id是否正确
			if(ids.size() != db_list.size()) {
				throw new Exception(Constant.FAIL_MSG_ID);
			}
			
			//待更新的实体，先移除缓存
			List<Basis> plist = new ArrayList<Basis>();
			for (Uploadable u : listE) {
				BasisDTO dto = (BasisDTO)u;
				//获取更新的省份、地市、区县，用于同步更新
				provinces.add(dto.getProvince());
				citys.add(dto.getCity());
				countrys.add(dto.getCountry());
				for(Basis b:db_list) {
					if(b.getId().toString().equals(dto.getId())) {
						plist.add(b);
						
						//初始化对象
						b.setByDTO(dto);
						b.setToday(DateUtils.dateToString(new Date(),"yyyy/MM/dd HH:mm:ss"));
						b.setDataer(request.getSession().getAttribute("username").toString());
						list.add(b);
						continue;
					}
				}
			}
			if(!list.isEmpty()) {
				removeToContext(plist);
				try {
					basisMapper.updateByList(list);
				} catch (Exception e) {
					addToContext(plist);
					throw e;
				}
				addToContext(list);
			}
		}
		
		//批量新增
		List<Uploadable> listN = map.get("N");
		if(listN!=null && !listN.isEmpty()) {
			//待新增的实体list
			List<Basis> list = new ArrayList<Basis>(listN.size()+1);
			for (Uploadable u : listN) {
				BasisDTO dto = (BasisDTO)u;
				//获取更新的省份、地市、区县，用于同步更新
				provinces.add(dto.getProvince());
				citys.add(dto.getCity());
				countrys.add(dto.getCountry());
				
				//封装数据
				Basis basis = new Basis();
				basis.setByDTO(dto);
		        basis.setToday(DateUtils.dateToString(new Date(),"yyyy/MM/dd HH:mm:ss"));
		        basis.setDataer(request.getSession().getAttribute("username").toString());
		        list.add(basis);
			}
			if(!list.isEmpty()) {
				basisMapper.insertByList(list);
				addToContext(list);
			}
		}
		
		// 同步更新：注册库、流向
		synchronizationService.syncUpdatePlansIgnoreXsCount(provinces, citys, countrys);
	}
	
	/***
     * 重复项判断时使用，新增了Basis或更新了Basis,同步更新到Context缓存里的数据
     * @param list
     */
    private void addToContext(List<Basis> list) throws Exception{
    	/***
    	 * 获取项目上下文的共享数据
    	 */
    	ServletContext servletContext = ServletContextUtils.getServletContext();
    	//基础库keys
    	Set<String> basicKeys = (Set<String>)servletContext.getAttribute("basicKeys");
    	//基础库省份
    	Set<String> provinces = (Set<String>)servletContext.getAttribute("provinces");
    	//基础库地市
    	Set<String> citys = (Set<String>)servletContext.getAttribute("citys");
    	//基础库区县
    	Set<String> countrys = (Set<String>)servletContext.getAttribute("countrys");
		for (Basis b : list) {
			basicKeys.add(StringUtil.concat(b.getProvince(),b.getCity(),b.getCountry(),b.getProduct(),b.getId()+""));
			provinces.add(b.getProvince());
			citys.add(b.getCity());
			countrys.add(b.getCountry());
		}
    }
    /***
     * 重复项判断时使用，新增了Basis或更新了Basis,同步更新到Context缓存里的数据
     * @param list
     */
    private void removeToContext(List<Basis> list) throws Exception{
    	/***
    	 * 获取项目上下文的共享数据
    	 */
    	ServletContext servletContext = ServletContextUtils.getServletContext();
    	//基础库keys
    	Set<String> basicKeys = (Set<String>)servletContext.getAttribute("basicKeys");
    	//基础库省份
    	Set<String> provinces = (Set<String>)servletContext.getAttribute("provinces");
    	//基础库地市
    	Set<String> citys = (Set<String>)servletContext.getAttribute("citys");
    	//基础库区县
    	Set<String> countrys = (Set<String>)servletContext.getAttribute("countrys");
    	for (Basis b : list) {
    		basicKeys.remove(StringUtil.concat(b.getProvince(),b.getCity(),b.getCountry(),b.getProduct(),b.getId()+""));
    		provinces.remove(b.getProvince());
    		citys.remove(b.getCity());
    		countrys.remove(b.getCountry());
    	}
    }
}
